package com.yiren.dbaa.module.practice_set.map.presenter;

import android.content.Context;

import com.yiren.backstage.config.api.LoadConfigApi;
import com.yiren.backstage.config.bean.device.StationParamConfigBean;
import com.yiren.backstage.config.bean.device.UserParamConfigBean;
import com.yiren.backstage.currency.bean.GpsInfoBean;
import com.yiren.backstage.currency.bean.PointBean;
import com.yiren.backstage.currency.entity.TrajectoryEntity;
import com.yiren.backstage.currency.entity.TrajectoryPointEntity;
import com.yiren.backstage.currency.utils.GpsUtil;
import com.yiren.backstage.db.dao.controller.TrajectDbController;
import com.yiren.dbaa.currency.model.MultiLaneModel;
import com.yiren.dbaa.module.practice_set.map.contract.CollectContract;
import com.yiren.dbaa.module.practice_set.map.model.CollectModel;
import com.yiren.dbaa.view.TrajectoryMapView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * @author lwb
 * @date : 2022/6/1 11:02
 * @description: presenter接口实现
 */
public class CollectPresenter implements CollectContract.Presenter {

    private Context context;
    private StationParamConfigBean stationParamConfig;
    private UserParamConfigBean userParamConfig;
    private CollectContract.Model model;
    private boolean isBaseCalibration;

    public CollectPresenter(Context context) {
        this.context = context;
        stationParamConfig = LoadConfigApi.loadStationParamConfig(context);
        userParamConfig = LoadConfigApi.loadUserParamConfig(context);
        model = new CollectModel(context);
        isBaseCalibration = model.loadPointCalibrationStatus(stationParamConfig.isBaseCalibration());
    }

    @Override
    public TrajectoryEntity saveTrajectory(int trajectoryType, boolean isAdd) {
        TrajectoryEntity trajectory = new TrajectoryEntity();
        trajectory.setId(UUID.randomUUID().toString());
        trajectory.setTrajectoryType(trajectoryType);
        //根据轨迹类型指定默认值
        trajectory.setLineWidth(15);
        if (trajectoryType == 9) {
            trajectory.setLineColor(2);
        } else {
            trajectory.setLineColor(1);
        }
        trajectory.setCollectDirection(1);
        trajectory.setCreateUser(String.valueOf(userParamConfig.getUserInfo().getId()));
        if (TrajectDbController.getInstance(false).insert(trajectory)) {
            return trajectory;
        }
        return null;
    }

    @Override
    public boolean updateTrajectory(TrajectoryEntity trajectory) {
        return TrajectDbController.getInstance(false).update(trajectory);
    }

    @Override
    public boolean saveTrajectoryPoint(TrajectoryPointEntity trajectoryPoint, int operCode) {
        return model.saveTrajectoryPoint(trajectoryPoint, operCode);
    }

    @Override
    public PointBean autoCollectPoint(PointBean lastAutoCollectPoint, TrajectoryEntity currentTrajectory, TrajectoryMapView mapView) {
        GpsInfoBean gpsInfo = GpsInfoBean.getInstance();
        double distance = 0;
        if (null != lastAutoCollectPoint) {
            if (isBaseCalibration && stationParamConfig.isBaseCalibration()) {
                String locations[] = stationParamConfig.getBaseStationLocation().split(",");
                float gpsX = GpsUtil.getDistanceX(Double.parseDouble(locations[0]), Double.parseDouble(locations[1]), gpsInfo.getLongitude());
                float gpsY = GpsUtil.getDistanceY(Double.parseDouble(locations[1]), gpsInfo.getLatitude());
                distance = Math.sqrt(Math.abs((lastAutoCollectPoint.getX() - gpsX) * (lastAutoCollectPoint.getX() - gpsX) + (lastAutoCollectPoint.getY() - gpsY) * (lastAutoCollectPoint.getY() - gpsY)));
            } else {
                distance = Math.sqrt(Math.abs((lastAutoCollectPoint.getX() - gpsInfo.getDistanceX()) * (lastAutoCollectPoint.getX() - gpsInfo.getDistanceX()) + (lastAutoCollectPoint.getY() - gpsInfo.getDistanceY()) * (lastAutoCollectPoint.getY() - gpsInfo.getDistanceY())));
            }
        }
        //自动采集间隔距离1米；如果大于10米，说明点位漂移了，则过滤掉
        if (null == lastAutoCollectPoint || (distance > 1 && distance < 10)) {
            //保存点位
            TrajectoryPointEntity trajectoryPoint = new TrajectoryPointEntity();
            PointBean point = setTrajectoryPoint(gpsInfo);
            trajectoryPoint.setPoint(point);
            trajectoryPoint.setTrajectory(currentTrajectory);
            trajectoryPoint.setTrajectoryId(currentTrajectory.getId());
            if (currentTrajectory.getTrajectoryType() == 9 || currentTrajectory.getTrajectoryType() == 19 || currentTrajectory.getTrajectoryType() == 20) {
                trajectoryPoint.setOrderIndex("1" + (mapView.trajectoryPoints.size() + 1));
            } else {
                trajectoryPoint.setOrderIndex((mapView.trajectoryPoints.size() + 1) + "");
            }
            if (saveTrajectoryPoint(trajectoryPoint, 1)) {
                mapView.trajectoryPoints.add(trajectoryPoint);
            }
            lastAutoCollectPoint = point;
        }
        if (distance >= 10) {  //这里防止采集的时候定位飘了，之后就不会继续采集点位的问题，因为distance一直大于10
            lastAutoCollectPoint = null;
        }
        return lastAutoCollectPoint;
    }

    @Override
    public void initTrajectoryPoints(TrajectoryMapView mapView) {
        if (null != mapView.trajectoryPoints) {
            mapView.trajectoryPoints.clear();
        }
        mapView.trajectoryPoints = new ArrayList<>();
    }

    @Override
    public boolean deleteTrajectory(TrajectoryEntity trajectoryEntity) {
        List<TrajectoryPointEntity> trajectoryPointList = TrajectDbController.getInstance(false).queryByNativeSql(TrajectoryPointEntity.class
                , "where trajectory_id = '" + trajectoryEntity.getId() + "'", null);
        for (TrajectoryPointEntity trajectoryPointEntity : trajectoryPointList) {
            if (!TrajectDbController.getInstance(false).delete(trajectoryPointEntity)) {
                return false;
            }
        }
        return TrajectDbController.getInstance(false).delete(trajectoryEntity);
    }

    @Override
    public boolean calibrationTrajectoryPoint(TrajectoryPointEntity trajectoryPoint, GpsInfoBean gpsInfo) {
        trajectoryPoint.setPoint(setTrajectoryPoint(gpsInfo));
        return saveTrajectoryPoint(trajectoryPoint, 2);
    }

    @Override
    public boolean deleteTrajectoryPoint(TrajectoryPointEntity trajectoryPoint) {
        return TrajectDbController.getInstance(false).delete(trajectoryPoint);
    }

    @Override
    public PointBean setTrajectoryPoint(GpsInfoBean gpsInfo) {
        return model.setTrajectoryPoint(gpsInfo);
    }

    @Override
    public MultiLaneModel setMultiLaneModel(TrajectoryMapView mapView, TrajectoryEntity trajectory, int position) {
        MultiLaneModel multiLaneModel = model.setMultiLaneModel();
        multiLaneModel.setNumber(mapView.laneLists.get(position).getNumber());
        multiLaneModel.setTrajectory(trajectory);
        return multiLaneModel;
    }

    @Override
    public void multiLaneTrajectorySave(TrajectoryMapView mapView) {
        for (int i = 0; i < mapView.laneLists.size(); i++) {
            final MultiLaneModel multiLaneModel = mapView.laneLists.get(i);
            TrajectoryEntity trajectory = multiLaneModel.getTrajectory();
            if (trajectory != null) {
                int lineType = multiLaneModel.getLineType();
                int trajectoryType = 1;
                switch (lineType) {
                    case 1:
                        trajectoryType = 1;
                        break;
                    case 2:
                        trajectoryType = 2;
                        break;
                    case 3:
                        trajectoryType = 7;
                        break;
                    case 4:
                        trajectoryType = 9;
                        break;
                    case 5:
                        trajectoryType = 19;
                        break;
                    case 6:
                        trajectoryType = 20;
                        break;
                }
                List<TrajectoryPointEntity> trajectoryPoints = multiLaneModel.getTrajectoryPoints();
                if (lineType == 1 || lineType == 2 || lineType == 3) {
                    for (int j = 0; j < trajectoryPoints.size(); j++) {
                        TrajectoryPointEntity trajectoryPoint = trajectoryPoints.get(j);
                        trajectoryPoint.setOrderIndex((j + 1) + "");
                        TrajectDbController.getInstance(false).update(trajectoryPoint);

                    }
                } else {
                    for (int j = 0; j < trajectoryPoints.size(); j++) {
                        TrajectoryPointEntity trajectoryPoint = trajectoryPoints.get(j);
                        trajectoryPoint.setOrderIndex("1" + (j + 1));
                        TrajectDbController.getInstance(false).update(trajectoryPoint);
                    }
                }
                trajectory.setTrajectoryType(trajectoryType);
                trajectory.setLineWidth(multiLaneModel.getLineWidth());
                trajectory.setLineColor(multiLaneModel.getLineColor());
                trajectory.setCollectDirection(1);
                updateTrajectory(trajectory);
                if (lineType == 4 || lineType == 5 || lineType == 6) {
                    float jjValue = -(multiLaneModel.getLineDis() + multiLaneModel.getLineWidth()) / 100.0f;
                    new Thread(() -> {
                        //保存双黄线左侧实线点位
                        model.saveSHXLeftPoint(multiLaneModel.getTrajectoryPoints(), jjValue);
                    }).start();
                }
            }
        }

    }

    @Override
    public void saveSHXLeftPoint(List<TrajectoryPointEntity> trajectoryPoints, float pyDistance) {
        model.saveSHXLeftPoint(trajectoryPoints, pyDistance);
    }

    @Override
    public boolean loadPointCalibrationStatus() {
        return model.loadPointCalibrationStatus(stationParamConfig.isBaseCalibration());
    }

    @Override
    public HashMap<String, List<TrajectoryPointEntity>> loadTrajectory(PointBean currentPoint, boolean isBaseCalibration) {
        //查询点位
        float secondSpeed = 100f;
        HashMap<String, List<TrajectoryPointEntity>> map;
        if (isBaseCalibration) {
            double secondLon = GpsUtil.getDistanceLon(secondSpeed, currentPoint.getLat());
            double secondLat = GpsUtil.getDistanceLat(secondSpeed);
            double minLon = currentPoint.getLon() - secondLon;
            double maxLon = currentPoint.getLon() + secondLon;
            double minLat = currentPoint.getLat() - secondLat;
            double maxLat = currentPoint.getLat() + secondLat;
            map = model.loadNearbyPoint(minLon, maxLon, minLat, maxLat, true);
        } else {
            float minX = currentPoint.getX() - secondSpeed;
            float maxX = currentPoint.getX() + secondSpeed;
            float minY = currentPoint.getY() - secondSpeed;
            float maxY = currentPoint.getY() + secondSpeed;
            map = model.loadNearbyPoint(minX, maxX, minY, maxY);
        }
        return map;
    }

    @Override
    public TrajectoryPointEntity loadMinTPoint(float x) {
        TrajectoryPointEntity tPoint = model.loadMinPoint(x, true);
        if (null == tPoint) {
            tPoint = model.loadMinPoint(x, false);
        }
        return tPoint;
    }

    @Override
    public TrajectoryPointEntity loadMinTPoint(double longitude, boolean flag) {
        TrajectoryPointEntity tPoint = model.loadMinPoint(longitude, true, flag);
        if (null == tPoint) {
            tPoint = model.loadMinPoint(longitude, false, flag);
        }
        return tPoint;
    }
}
